package com.example.blog.utils;

import com.example.blog.constants.Constant;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtParser;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;

import java.security.Key;
import java.util.Date;
import java.util.Map;

@Slf4j
public class JwtUtil {
    // 过期时间
    private static final long EXPIRATION_TIME = 60 * 60 * 1000;
    // 生成的字符串
    private static final String secretKey = "Lgo2v38vK8lNfzwbDW7ZmlZ9Sps5TF98JOcnjbs7f4g";
    // 字符串再解码成 key
    private static final Key key = Keys.hmacShaKeyFor(Decoders.BASE64URL.decode(secretKey));

    public static String genJwtToken(Map<String, Object> claim){
        // 1. 调用 jwt 的 api，生成 token - 生成 token 需要密钥，用于生成签名
        String jwtToken = Jwts.builder()
                .setClaims(claim)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(key)
                .compact();

        return jwtToken;
    }

    public void genKey(){
        // 1. 生成 key
        Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
        // 2. 对 key 进行 Base64 编码
        String secretKey = Encoders.BASE64URL.encode(key.getEncoded());

        System.out.println(secretKey);
    }

    // 2. 校验 JWT 令牌
    public static Claims verifyJwt(String token){
        log.info("接收到 token: {}", token);
        // 1. 生成一个用于校验的对象
        JwtParser parser = Jwts.parserBuilder().setSigningKey(key).build();
        // 2. 调用 api 进行校验
        Claims claims = null;
        try{
            claims = parser.parseClaimsJws(token).getBody();
            if(claims == null){
                log.error("token 不正确");
                return null;
            }
        }catch(Exception e){
            log.error("解析 token 失败");
            return null;
        }
        return claims;
    }

    // 返回当前登录用户的 id
    public static Integer getCurrentUserIdByToken(String token){
        // 1. 解析 token，获取用户信息
        Claims claims = JwtUtil.verifyJwt(token);
        // 2. 拿到用户 id
        Integer id = (Integer) claims.get(Constant.TOKEN_USER_ID);

        return id;
    }
}
